﻿// backgroundDetection.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>

using namespace cv;
using namespace std;

int labelTargets(Mat &src, Mat &mask,Mat &fore, int thresh = 100)
{
	//以下是图像分割
	Mat seg = mask.clone();
	vector<vector<Point>> cnts;
	findContours(seg, cnts, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

	//以下进行筛选
	float area;//面积
	Rect rect;//计算轮廓包围的矩形
	int count = 0;
	string strCount;

	for (int i = 0; i < cnts.size(); i++)
	{
		vector<Point> c = cnts[i];
		area = contourArea(c);//计算每个轮廓的面积

		if (area < thresh)
		{
			continue; //滤除面积小于thres的分割结果：可能是噪声
		}
		count++; //统计运动目标的数量
		rect = boundingRect(c);

		//在原始图形上画出包围矩形，并给每个矩形标号
		rectangle(fore, rect, Scalar(0,0,255), 1);

		stringstream ss;
		ss << count;
		ss >> strCount;
		putText(fore, strCount, Point(rect.x, rect.y), CV_FONT_HERSHEY_PLAIN, 1, Scalar(0,0,255));
		cout << "第" << count << "个矩形的坐标：(" << rect.x <<","<<rect.y<<")"<< endl;
		cout << "     矩形面积：" << rect.height*rect.width << endl;
		cout << "     矩形周长：" << 2*(rect.height+rect.width) << endl;
		imshow("前景分割", fore);

	}
	return count;
}

int main()
{
	const char *fn = "E:\\VC_project\\video\\vtest.avi";
	VideoCapture cap;
	Mat source, image, foreGround, backGround, fgMask;
	Ptr<BackgroundSubtractor> pBgModel =
		createBackgroundSubtractorMOG2().dynamicCast<BackgroundSubtractor>();

	cap.open(fn);
	if (!cap.isOpened())
	{
		cout << "无法打开视频文件：" << fn << endl;
	}

	for (;;)
	{
		cap >> source; //将读取的每一帧图像传给source
		if (source.empty())
			break;

		resize(source, image, Size(source.cols / 2, source.rows / 2), INTER_LINEAR);

		if (foreGround.empty())
		{
			foreGround.create(image.size(), image.type());//创建空白窗口
		}
		pBgModel->apply(image, fgMask);

		threshold(fgMask, fgMask, 30, 255, THRESH_BINARY);

		foreGround = Scalar::all(0);
		image.copyTo(foreGround,fgMask);
		//标记找到的运动目标
		int nTargets = labelTargets(image, fgMask, foreGround);
		cout << "共检测到" << nTargets << "个目标" << endl;

		pBgModel->getBackgroundImage(backGround);

		//显示原始图像及背景，前景
		imshow("Source", source);
		imshow("BackGround", backGround);
		imshow("ForeGround", foreGround);
		imshow("ForeGround Mask", fgMask);

		//以下检测是否终止（按下ESC，对应ASCII 27）
		char key = waitKey(100);//每一帧等待100ms
		if (key == 27)
			break;

	}


	waitKey();

	
	
}


